import { PlusOutlined } from '@ant-design/icons'
import { Button, Popover, Table } from 'antd'
import { nanoid } from 'nanoid'
import { useEffect, useState } from 'react'

import {
  cancelCompanionOrderApi,
  changeNursingWorkerApi,
  createPcTradeOrderApi,
  getAppIdApi,
  getCompanionOrderApi,
  getPayableAmountByOrderIdApi,
  getTradeOrderListByOrderIdApi,
  orderRenewApi,
} from '@/api/pcs/pcsCompanionOrder'
import AekButton from '@/components/AekButton'
import AekDrawer, { PromiseThen } from '@/components/AekDrawer'
import AekForm from '@/components/AekForm'
import { PromiseForm } from '@/components/AekModal'
import APanel from '@/components/APanel'
import Ellipsis from '@/components/Ellipsis'
import StarRate from '@/components/StarRate'
import { message, modal, renderIndexColumn } from '@/utils/antdHelper'
import { formatDate, formatDateTime, formatMoneyNum } from '@/utils/displayHelper'
import {
  ACCOMPANYING_PERIOD_ENUM,
  GENDER_ENUM,
  PCS_COMBO_TYPE_ENUM,
  PCS_COMPANION_ORDER_CANCELTYPE_ENUM,
  PCS_COMPANION_ORDER_STATUS_ENUM,
  PCS_COMPANION_PERIOD_ENUM,
  PCS_COMPANION_TYPE_ENUM,
  PCS_COMPANION_WAY_ENUM,
} from '@/utils/enum'
import { requestWithTry } from '@/utils/request'

import AccompanyingPlanCard from '../AccompanyingPlanCard'
import AccompanyingPlanDrawer from '../AccompanyingPlanDrawer'
import PayModal from '../PayModal'
import RenewModal from '../RenewModal'
import SelNursingWorkerModal from '../SelNursingWorkerModal'
import StopModal from '../StopModal'

/**
 * @typedef {Object} OtherProps
 * @property {string | number} [id] 单据id
 * @property {boolean} [hideOperate] 是否隐藏操作按钮
 * @property {() => void} [afterClose] 关闭弹窗之后的回调
 */

/**
 * @typedef {import("antd/es/drawer").DrawerProps & OtherProps} DetailDrawerProps
 */

/**
 * 陪护订单详情抽屉
 * @param {DetailDrawerProps} param0
 */
const DetailDrawer = ({ id, hideOperate = false, afterClose }) => {
  const [detailData, setDetailData] = useState({})
  const [loading, setLoading] = useState(false)
  const [tableNeedRefresh, setTableNeedRefresh] = useState(false)
  const [orderList, setOrderList] = useState([])

  const getDetail = async () => {
    setLoading(true)
    const { data } = await requestWithTry(getCompanionOrderApi, {
      id,
    }).finally(() => setLoading(false))
    setDetailData(data)

    const { data: orderList } = await requestWithTry(getTradeOrderListByOrderIdApi, { orderId: id })
    setOrderList(orderList)
  }

  useEffect(() => {
    if (!id) return
    getDetail()
  }, [id])

  const accompanyingPlan = async () => {
    await AccompanyingPlanDrawer.PromiseThen({
      detailData,
    })
    message.success('添加成功')
    await getDetail()
    setTableNeedRefresh(true)
  }

  const renew = async () => {
    const { datePicker, select } = await RenewModal.PromiseThen({ detailData })
    await requestWithTry(orderRenewApi, {
      orderId: detailData.id,
      endDate: formatDate(datePicker),
      endPeriod: select,
    })
    message.success('服务续期成功')
    await getDetail()
  }

  const changeNursingWorker = async () => {
    const { nursingWorke, effective } = await SelNursingWorkerModal.PromiseThen({
      oldNursingWorkeId: detailData.orderDetail?.orderDetailNursingWorkerList?.[0]?.nursingWorkersId,
      companionType: detailData.orderDetail?.companionType,
      companionCompanyId: detailData.orderDetail?.companionCompanyId,
      patientName: detailData.patientName,
      phoneNo: detailData.phoneNo,
      orderNo: detailData.orderNo,
      isChange: true,
      startDate: detailData.orderDetail?.startDate,
      startPeriod: detailData.orderDetail?.startPeriod,
      endDate: detailData.orderDetail?.endDate,
      endPeriod: detailData.orderDetail?.endPeriod,
    })
    const params = {
      id: detailData.id,
      orderDetailId: detailData.orderDetail.id,
      nursingWorkersId: nursingWorke.id,
      effectiveDate: formatDate(effective.datePicker),
      effectivePeriod: effective.select,
    }
    await requestWithTry(changeNursingWorkerApi, params)
    message.success('更换护工成功')
    await getDetail()
  }

  const onCancel = async () => {
    modal.confirm({
      title: '确认取消订单?',
      onOk: async () => {
        await requestWithTry(cancelCompanionOrderApi, { id: detailData.id })
        message.success('取消订单成功')
        await getDetail()
        setTableNeedRefresh(true)
      },
    })
  }

  const onSubmit = async () => {
    let payableAmount
    if (detailData.status === PCS_COMPANION_ORDER_STATUS_ENUM.BE_PAID) {
      const { data } = await requestWithTry(getPayableAmountByOrderIdApi, { id: detailData.id })
      payableAmount = data.payableAmount
    } else {
      const values = await PromiseForm.PromiseThen({
        title: '请输入支付金额',
        formData: [
          {
            field: 'payableAmount',
            label: '金额',
            formItemProps: {
              rules: [{ required: true }],
            },
            component: {
              name: 'AekInputNumber',
            },
          },
        ],
      })
      payableAmount = values.payableAmount
    }

    const { data } = await requestWithTry(createPcTradeOrderApi, {
      orderId: detailData.id,
      payAmount: payableAmount,
    })
    const { data: appId } = await requestWithTry(getAppIdApi)
    const production = location.href.includes('https://yunhe.aek56.com/') ? 'production' : 'test'
    const paid = await PayModal.PromiseThen({
      tradeId: data.tradeId,
      fileUrl: data.fileUrl,
      startDate: detailData.orderDetail.startDate,
      startPeriod: detailData.orderDetail.startPeriod,
      endDate: detailData.orderDetail.endDate,
      endPeriod: detailData.orderDetail.endPeriod,
      payableAmount,
      day: detailData.orderDetail.serviceDays,
      qrcodeUrl: `https://yunhe.aek56.com/${appId}?mode=${production}&redirect=orderDetail&id=${detailData.id}`,
    })
    if (paid) {
      message.success('支付成功')
      await getDetail()
      setTableNeedRefresh(true)
    }
  }

  const onStop = async () => {
    await StopModal.PromiseThen({
      detailData,
    })
    message.success('终止服务成功')
    await getDetail()
    setTableNeedRefresh(true)
  }

  /** 待沟通 */
  const beCommunicated = detailData.status === PCS_COMPANION_ORDER_STATUS_ENUM.BE_COMMUNICATED
  /** 待支付 */
  const bePaid = detailData.status === PCS_COMPANION_ORDER_STATUS_ENUM.BE_PAID
  /** 服务中 */
  const inService = detailData.status === PCS_COMPANION_ORDER_STATUS_ENUM.IN_SERVICE
  /** 已完成 */
  const completed = detailData.status === PCS_COMPANION_ORDER_STATUS_ENUM.COMPLETED
  /** 待沟通已取消 */
  const communicateCanceled =
    detailData.status === PCS_COMPANION_ORDER_STATUS_ENUM.CANCELED &&
    detailData.cancelType === PCS_COMPANION_ORDER_CANCELTYPE_ENUM.CANCELLATION_TO_BE_COMMUNICATED

  /** 待支付已取消 */
  const paidCanceled =
    detailData.status === PCS_COMPANION_ORDER_STATUS_ENUM.CANCELED &&
    detailData.cancelType === PCS_COMPANION_ORDER_CANCELTYPE_ENUM.CANCELLATION_TO_BE_PAID

  return (
    <AekDrawer
      title={`${PCS_COMPANION_ORDER_STATUS_ENUM.getText(detailData.status) || ''}详情`}
      width='90%'
      loading={loading}
      afterClose={() => afterClose?.(tableNeedRefresh)}
      showFooter={!hideOperate && (beCommunicated || bePaid || inService)}
      footer={
        <>
          {beCommunicated && <AekButton onSubmit={onCancel}>取消订单</AekButton>}
          {bePaid && (
            <Button type='primary' onClick={onSubmit}>
              支付
            </Button>
          )}
          {inService && (
            <>
              {detailData.orderDetail?.endDate && (
                <Button type='primary' onClick={renew}>
                  服务续期
                </Button>
              )}
              <Button type='primary' onClick={changeNursingWorker}>
                更换护工
              </Button>
              <AekButton onSubmit={onStop}>终止服务</AekButton>
            </>
          )}
        </>
      }
    >
      {beCommunicated && (
        <APanel title='套餐方案'>
          <div
            className='h44px b-rd-4px bg-#F9F9F9 b-t-2px b-t-#BDCDE4 b-t-solid flex cursor-pointer items-center justify-center'
            onClick={() => accompanyingPlan()}
          >
            <PlusOutlined />
            <span className='ml8px'>添加方案</span>
          </div>
        </APanel>
      )}
      {(bePaid || inService || completed || paidCanceled) && (
        <APanel title='套餐方案'>
          <AccompanyingPlanCard detailData={detailData} />
        </APanel>
      )}
      <APanel title='订单信息'>
        <AekForm
          allView
          detail={detailData}
          col={6}
          formData={[
            { field: 'orderNo', label: '订单号' },
            { field: 'status', label: '订单状态', enum: PCS_COMPANION_ORDER_STATUS_ENUM },
            { field: 'operatorName', label: '下单人' },
            { field: 'operatorTime', label: '下单时间', isDateTime: true },
            { exclude: !(communicateCanceled || paidCanceled), field: 'cancelUserName', label: '取消人' },
            {
              exclude: !(communicateCanceled || paidCanceled),
              field: 'cancelTime',
              label: '取消时间',
              isDateTime: true,
            },
            { exclude: !completed, field: 'finishTime', label: '完成时间', isDateTime: true },
            { field: 'comboType', label: '订单类型', enum: PCS_COMBO_TYPE_ENUM },
          ]}
        />
      </APanel>
      <APanel title='患者信息'>
        <AekForm
          allView
          detail={detailData}
          col={6}
          formData={[
            { field: 'patientName', label: '姓名' },
            ...(bePaid || inService || completed || paidCanceled
              ? [
                  { field: 'gender', label: '性别', enum: GENDER_ENUM },
                  { field: 'idCard', label: '身份证号' },
                ]
              : []),
            { field: 'phoneNo', label: '手机号' },
            ...(bePaid || inService || completed || paidCanceled
              ? [
                  { field: 'medicalRecordNo', label: '病历号' },
                  { field: 'inpatientNo', label: '住院号' },
                  { field: 'familyName', label: '家属姓名' },
                  { field: 'familyPhoneNo', label: '家属电话' },
                ]
              : []),
          ]}
        />
      </APanel>
      <APanel title='服务信息'>
        <AekForm
          allView
          detail={detailData}
          col={6}
          formData={[
            {
              exclude: !(bePaid || inService || completed || paidCanceled),
              field: ['orderDetail', 'companionType'],
              label: '陪护类型',
              enum: PCS_COMPANION_TYPE_ENUM,
            },
            { field: 'hospitalName', label: '医院' },
            { field: 'inpatientWardName', label: '病区' },
            { field: 'bedNumber', label: '床位' },
            {
              exclude: !(beCommunicated || communicateCanceled),
              field: 'companionComboName',
              label: '意向套餐',
            },
            ...(bePaid || inService || completed || paidCanceled
              ? [
                  { field: ['orderDetail', 'companionCompanyName'], label: '陪护公司' },
                  {
                    label: '开始时间',
                    viewRender: (_, detail) =>
                      `${formatDate(detail.orderDetail?.startDate)} ${PCS_COMPANION_PERIOD_ENUM.getText(
                        detail.orderDetail?.startPeriod,
                      )}`,
                  },
                  {
                    label: '结束时间',
                    viewRender: (_, detail) =>
                      `${formatDate(detail.orderDetail?.endDate) || ''} ${
                        PCS_COMPANION_PERIOD_ENUM.getText(detail.orderDetail?.endPeriod) || ''
                      }`,
                  },
                  {
                    field: ['orderDetail', 'servicePeriod'],
                    label: '陪护时段',
                    viewRender: value => ACCOMPANYING_PERIOD_ENUM.getText(value),
                  },
                  {
                    field: ['orderDetail', 'orderDetailNursingWorkerList'],
                    label: '护工',
                    viewRender: value => (
                      <Popover
                        content={
                          <Table
                            rowKey='id'
                            bordered
                            columns={[
                              { dataIndex: 'nursingWorkersName', title: '姓名' },
                              { dataIndex: 'nursingWorkersPhoneNo', title: '电话' },
                              {
                                dataIndex: 'time',
                                title: '服务时间',
                                render: (_, { startDate, startPeriod, endDate, endPeriod }) =>
                                  `${formatDate(startDate)} ${PCS_COMPANION_PERIOD_ENUM.getText(startPeriod)} ~ ${
                                    formatDate(endDate) || ''
                                  } ${PCS_COMPANION_PERIOD_ENUM.getText(endPeriod) || ''}`,
                              },
                            ]}
                            dataSource={value || []}
                            pagination={false}
                          />
                        }
                      >
                        <a>{value?.[0]?.nursingWorkersName}</a>
                      </Popover>
                    ),
                  },
                  {
                    field: ['orderDetail', 'orderDetailNursingWorkerList', '0', 'nursingWorkersPhoneNo'],
                    label: '护工电话',
                  },
                  { field: ['orderDetail', 'companionComboName'], label: '套餐名称' },
                  {
                    field: ['orderDetail', 'companionComboContent'],
                    label: '套餐内容',
                    viewRender: value => (
                      <Ellipsis tooltip lines={1}>
                        {value}
                      </Ellipsis>
                    ),
                  },
                  {
                    field: ['orderDetail', 'companionComboCompanionWay'],
                    label: '陪护方式',
                    enum: PCS_COMPANION_WAY_ENUM,
                  },
                  {
                    field: ['orderDetail', 'price'],
                    label: '收费标准',
                    viewRender: value => (
                      <span>
                        <span className='c-money'>{formatMoneyNum(value || 0)}</span> / 天
                      </span>
                    ),
                  },
                ]
              : []),
          ]}
        />
      </APanel>
      {(inService || completed || bePaid) && (
        <>
          <APanel title='结算信息'>
            <Table
              rowKey={() => nanoid()}
              columns={[
                renderIndexColumn(),
                {
                  dataIndex: 'totalAmount',
                  title: '总金额',
                  render: value => <span className='c-money'>{formatMoneyNum(value || 0)}</span>,
                },
                { dataIndex: 'payTime', title: '付款时间', render: formatDateTime },
              ]}
              dataSource={orderList}
              pagination={false}
            />
          </APanel>
          {!bePaid && (
            <APanel title='评价内容'>
              <AekForm
                allView
                detail={detailData}
                formData={[
                  {
                    field: ['orderComment', 'serviceComment'],
                    label: '服务评价',
                    viewRender: value => <StarRate value={value} />,
                  },
                  { field: ['orderComment', 'remark'], label: '备注' },
                ]}
              />
            </APanel>
          )}
        </>
      )}
    </AekDrawer>
  )
}

/**@type {(props?: DetailDrawerProps) => Promise<any>} */
DetailDrawer.PromiseThen = PromiseThen

export default DetailDrawer
